import time
import traceback
from Basic.read_excel import OpenpyxlExcel
from FindElement.operateElement import OperateElement
from FindElement.getElement import GetElement
from Basic.read_ini import ReadIni
from Basic.base_log import log
from Basic.PATH import *
from Basic.read_re import re_sub
from Basic.api_mysql import pymysqlHandle
class PerformElement(object):
    def __init__(self, driver, add_img, get_assert):
        self.driver = driver
        self.get_assert = get_assert
        self.add_img = add_img
        # self.get_assert = get_assert
        self.readini = ReadIni()

    def main_Test(self, caseMoudleName, filename, sheetname):  # caseMoudle：用例模块名称
        # print('开始执行用例')
        flag = True
        try:
            excel = OpenpyxlExcel(filename=filename, sheetname=sheetname)  # 实例化excel
            # 获取所有用例模块及其所在行数范围，返回值为字典如 {'LOGIN':[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}
            AllCaseMoudleDict = excel.get_caseMoud_AllLine(filename=filename, sheetname=sheetname)
            # print(AllCaseMoudleDict)
            # 根据用例模块名称获取该模块所在的行数列表，如 [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
            caseMoudleList = AllCaseMoudleDict[caseMoudleName]
            # 打印用例模块所在行数信息，如 -- 0 --> LOGIN 所在用例区间：[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
            log.info('-- 0 --> %s 所在用例区间：%s' % (caseMoudleName, caseMoudleList))

            # 遍历用例所在区间的每行
            i = 0
            while i < len(caseMoudleList):
                excel = OpenpyxlExcel(filename=filename, sheetname=sheetname)  # 实例化excel
                # 获取excel第 i行的所有值，返回一个字典
                caseDict = excel.get_row_cells(filename=filename, sheetname=sheetname, rows=caseMoudleList[i])
                # 替换变量
                if caseDict['操作元素']  is not None:
                    caseDict['操作元素'] = re_sub(caseDict['操作元素'], var_dict)
                if caseDict['断言元素'] is not None:
                    caseDict['断言元素'] = re_sub(caseDict['断言元素'], var_dict)
                if caseDict['输入数据'] is not None:
                    caseDict['输入数据'] = re_sub(caseDict['输入数据'], var_dict)
                if caseDict['预期结果'] is not None:
                    caseDict['预期结果'] = re_sub(caseDict['预期结果'], var_dict)

                # 判断该行是否执行
                if caseDict['是否执行'] == '否':
                    log.info('-- %s --> %s:  该步骤状态为否，跳过执行' % (caseDict['编号'], caseDict['操作步骤']))
                    excel.write_excel(filename, sheetname, caseMoudleList[i], 15, 'SKIP')
                    excel.write_excel(filename, sheetname, caseMoudleList[i], 16, datatime)  # 在excel 填写测试时间
                    # self.notcase = 1
                    i = i + 1
                    continue

                # log.info('前提条件：%s'% caseDict['前提条件'])
                #判断前提条件是否通过
                if caseDict['编号'] != 1:
                    res = excel.get_precondition_assertresult(caseDict, excel.get_sheet(filename, sheetname))
                    if  res != 'PASS':
                        log.info('-- %s --> %s:  该步骤状态前提条件未执行通过，跳过执行' % (
                        caseDict['编号'], caseDict['操作步骤']))
                        excel.write_excel(filename, sheetname, caseMoudleList[i], 15, 'N/A')
                        excel.write_excel(filename, sheetname, caseMoudleList[i], 16, datatime)  # 在excel 填写测试时间
                        i = i + 1
                        continue

                # 判断是否只断言,如果没有元素定位方式则只做断言
                if caseDict['元素定位方式'] != None and caseDict['元素定位方式'] != '':
                    # 获取元素对象
                    self.getElement = GetElement(self.driver)
                    ele = self.getElement.get_ele(caseDict)
                    if ele == None or ele == False:
                        log.info('--  --> :  get_element 操作类型未匹配 或者 获取不到ele')
                        log.info('--  --> 将测试结果写入EXCEL（第%s行，第%s列）:%s' % (caseMoudleList[i], 15, 'FALSE'))
                        excel.write_excel(filename, sheetname, caseMoudleList[i], 15, 'FALSE')
                        excel.write_excel(filename, sheetname, caseMoudleList[i], 16, datatime)  # 在excel 填写测试时间
                        flag = False
                        i = i + 1
                        continue

                    # 对元素进行操作
                    self.operateElement = OperateElement(self.driver, self.add_img)
                    value = self.operateElement.opera_element(ele, caseDict)  # 获取EXCEL，执行相应操作。返回获取到的元素文本或者元素值或者空值
                    if value == None or value == False:
                        log.info('--  --> :  opera_element 断言出错  或者 操作异常')
                        log.info('-- %s --> 将测试结果写入EXCEL（第%s行，第%s列）:%s' % (value, caseMoudleList[i]+1, 15, 'FALSE'))
                        excel.write_excel(filename, sheetname, caseMoudleList[i], 15, 'FALSE')
                        excel.write_excel(filename, sheetname, caseMoudleList[i], 16, datatime)  # 在excel 填写测试时间
                        flag = False
                        i = i + 1
                        continue

                    # 测试失败则回退至某行：元素定位必须时ifele,且输入数据格式是while_case = 用例编号，
                    if caseDict['元素定位方式'] == 'ifele' and 'while_case' in caseDict['输入数据'] and 'timesleep' not in str(caseDict['输入数据']):
                        i = i - int(caseDict['输入数据'])
                        log.info('--   --> 检测到该元素存在，回退到第 %s 条(行)用例' % i)
                        time.sleep(1)
                        continue

                    # 延时：元素定位是输入数据,且输入数据格式是time_sleep = 延时时间（秒），
                    if str(caseDict['元素定位方式']) != 'sendkey' and 'time_sleep' in str(caseDict['输入数据']):
                        ts=float(str(caseDict['输入数据']).split('=')[1].strip())
                        log.info('--   --> 等待 %s 秒' % ts)
                        time.sleep(ts)


                # 判断是否断言,如果没有断言元素定位方式则不断言
                if caseDict['断言元素方法'] != None and caseDict['断言元素方法'] != '':
                    #执行断言
                    value = self.assert_main(caseDict)

                # *******EXCEL相关操作：
                excel.write_excel(filename, sheetname, caseMoudleList[i], 16, datatime)# 在excel 填写测试完成时间

                if caseDict['元素定位方式'] == 'getcode':
                    log.info('--   --> 将验证码结果写入EXCEL（第%s行，第%s列）:%s' % (caseMoudleList[i] + 1, 8, value))
                    excel.write_excel(filename, sheetname, caseMoudleList[i] + 1, 8, value)  # 在excel 测试报告 栏上写入值：
                if caseDict['元素定位方式'] == 'text':
                    log.info(
                        '--   --> 将获取到的元素text写入EXCEL（第%s行，第%s列）:%s' % (caseMoudleList[i] + 1, 8, value))
                    excel.write_excel(filename, sheetname, caseMoudleList[i] + 1, 8, value)  # 在excel 测试报告 栏上写入值：

                if value:
                    # log.info('--   --> 将测试结果写入EXCEL（第%s行，第%s列）:%s' % (caseMoudleList[i], 15, 'PASS'))
                    excel.write_excel(filename, sheetname, caseMoudleList[i], 15, 'PASS')  #
                else:
                    log.info('--   --> 将测试结果写入EXCEL（第%s行，第%s列）:%s' % (caseMoudleList[i], 15, 'FALSE'))
                    excel.write_excel(filename, sheetname, caseMoudleList[i], 15, 'FALSE')  #
                    flag = False
                # while循环值加1
                i = i + 1
        except:
            error_log = "*××××××××××××××××××performElement 出错××××××××××××××××××\n %s" % traceback.format_exc()  # 打印异常信息
            self.add_img()
            # self.readini.set_value('error', 'error_log', error_log)
            log.info(error_log)
            return False
        return flag


    def assert_main(self,caseDict):
        # 获取元素对象
        self.getElement = GetElement(self.driver)
        ele = self.getElement.get_ele(caseDict, True)
        if ele == None or ele == False:
            log.info('--  --> :  assert_get_element 操作类型未匹配 或者 获取不到ele')
            # self.get_assert('assertTrue',False,False)
            return False
        # 对元素进行操作
        if caseDict['断言元素动作'] == 'ele':
            log.info('--   --> 执行断言，判断元素是否存在，预期结果：%s ' % (ele))
            if ele:
                # self.get_assert(caseDict['断言方法'], ele, caseDict['预期结果'])
                return True
            else:
                return False
        if caseDict['断言元素动作'] == 'text':
            log.info('--   --> 执行断言，预期结果：%s，实际结果：%s ' % (caseDict['预期结果'], ele.text))
            return self.get_assert(caseDict['断言方法'], ele.text, caseDict['预期结果'])
        if caseDict['断言元素动作'] == 'sql':
            # 执行sql,链接数据库
            db = pymysqlHandle('root', 'root','3306','database' )
            expect_resulet = db.selectDb(caseDict['预期结果'])
            log.info('--   --> 执行断言，预期结果：%s，实际结果：%s ' % (expect_resulet, ele.text ))
            return self.get_assert(caseDict['断言方法'], ele.text, expect_resulet)



if __name__ == "__main__":
    # filname = 'E://PythonWorkspace//RunTest//LZ_Element.xlsx'
    # datatime = time.strftime('%Y-%m-%d %H.%M.%S', time.localtime(time.time()))  # 创建时间
    # sheetname = '6101'
    # # 初始化 seleium
    # driver = webdriver.Chrome()
    # driver.maximize_window()
    #
    # excel = openpyxlExcel.GetExcel(filename=filname, sheetname=sheetname)
    # caseList = excel.get_CaseMoud_rows(case='LOGIN')  # 获取用例模块所在行数区间
    # # log.info(caseList)
    # fm = LZElement(driver, datatime)
    #
    # for i in range(len(caseList)):
    #     caseDict = excel.get_CaseMoud_rows(caseList[i])
    #     # log.info('获取指定行数内容caseDict : %s' % caseDict)
    #     # log.info('%s:%s' % (caseDict['操作步骤'], caseDict['输入数据']))
    #     fm.opera_element(caseDict)
    pass
